package com.mallcai.bigdata.ladon.service.report;

import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.Cached;
import com.mallcai.bigdata.ladon.dpl.entity.report.QueryField;
import com.mallcai.bigdata.ladon.dpl.entity.report.Report;
import com.mallcai.bigdata.ladon.dpl.entity.report.ReportColumn;
import com.mallcai.bigdata.ladon.dpl.entity.report.ReportSql;
import com.mallcai.bigdata.ladon.service.report.impl.ReportQueryConstants;
import com.mallcai.bigdata.ladon.vo.args.QueryArg;
import com.mallcai.bigdata.ladon.vo.system.MenuVo;
import com.mallcai.bigdata.ladon.vo.system.TreeNodeVo;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by oneape<oneape15@163.com>
 * Created 2019-07-09 11:09.
 * Modify:
 */
public interface IReportService {

    public static final int CODE_LEN = 10;

    public static final int QUERY_FIELD_UPLINK_MAX = 4;  // 查询参数最大级联深度

    /**
     * 添加
     *
     * @param report   Report
     * @param groupIds List 所属报表组
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_BY_ID, key = "args[0].getId()")
    int addReport(Report report, List<Long> groupIds);

    /**
     * 修改
     *
     * @param report   Report
     * @param groupIds List 所属报表组
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_BY_ID, key = "args[0].getId()")
    int editReport(Report report, List<Long> groupIds);

    /**
     * 删除
     *
     * @param report Report
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_BY_ID, key = "args[0].getId()")
    int delReport(Report report);

    /**
     * 根据Id获取
     *
     * @param reportId Long
     * @return Report
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_BY_ID, key = "args[0]",
            expire = 10, timeUnit = TimeUnit.MINUTES)
    Report getById(Long reportId);

    /**
     * 根据条件查询报表
     *
     * @param params Map
     * @return List
     */
    List<Report> getByParams(Map<String, Object> params);

    /**
     * 保存报表查询SQL
     *
     * @param reportId  Long
     * @param reportSql ReportSql
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_SQL, key = "args[1].id")
    int saveReportSql(Long reportId, ReportSql reportSql);

    /**
     * 根据SQL主键获取详细信息
     *
     * @param sqlId Long
     * @return ReportSql
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_SQL, key = "args[0]", expire = 10, timeUnit = TimeUnit.MINUTES)
    ReportSql getSqlInfoById(Long sqlId);

    /**
     * 保存查询参数
     *
     * @param reportId Long
     * @param fields   List
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_QUERY_FIELDS, key = "args[0]")
    int saveQueryFields(Long reportId, List<QueryField> fields);

    /**
     * 获取查询参数
     *
     * @param reportId Long
     * @return List
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_QUERY_FIELDS, key = "args[0]", expire = 10, timeUnit = TimeUnit.MINUTES)
    List<QueryField> getQueryFields(Long reportId);

    /**
     * 保存报表字段列表
     *
     * @param reportId Long
     * @param columns  List
     * @return int
     */
    @CacheInvalidate(name = ReportQueryConstants.CACHE_GET_COLUMNS, key = "args[0]")
    int saveReportColumns(Long reportId, List<ReportColumn> columns);

    /**
     * 获取报表参数列表
     *
     * @param reportId Long
     * @return List
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_COLUMNS, key = "args[0]", expire = 10, timeUnit = TimeUnit.MINUTES)
    List<ReportColumn> getReportColumns(Long reportId);

    /**
     * 根据code查询出report对象
     *
     * @param code
     * @return
     */
    default Report getByCode(String code) {
        return getById(getIdByCode(code));
    }

    /**
     * 根据code获取id,由于code不能修改,所以缓存可以设置的很长
     *
     * @param code:报表编码
     * @return long: 报表id
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_ID_BY_CODE, key = "args[0]", expire = 1, timeUnit = TimeUnit.DAYS)
    Long getIdByCode(String code);

    /**
     * 根据id获取code
     *
     * @param id 报表Id
     * @return String 报表Code
     */
    @Cached(name = ReportQueryConstants.CACHE_GET_CODE_BY_ID, key = "args[0]", expire = 1, timeUnit = TimeUnit.DAYS)
    String getCodeById(Long id);


    /**
     * 获取报表树
     *
     * @param simpleReport null - 查询所有; 0 - 普通报表; 1 - 简单的报表(LOV);
     * @param filterIds    List 过滤掉的报表Id
     * @param fixOption    String 携带特定值, NULL, ALL
     * @return List
     */
    List<TreeNodeVo> getReportTree(Integer simpleReport, List<Long> filterIds, String fixOption);

    /**
     * 获取用户拥有的报表菜单列表
     *
     * @param userId  Long 用户Id
     * @param roleIds List<Long> 角色id列表
     * @return List
     */
    List<MenuVo> getReportTreeOfMenu(Long userId, List<Long> roleIds);

    /**
     * 获取报表查询参数信息
     *
     * @param reportId Long
     * @return List
     */
    List<QueryArg> getReportQueryArgs(Long reportId);

    /**
     * 根据报表id复制一份新的报表
     *
     * @param reportId Long 报表id
     */
    int copyReport(Long reportId);

    /**
     * 获取全部的报表code以及名字
     */
    List<Report> getReportCodeAndName();

    /**
     * 获取报表数量
     *
     * @return int
     */
    @Cached(expire = 1, timeUnit = TimeUnit.MINUTES)
    int getReportSize();

    /**
     * 通过报表编码查询报表实体
     *
     * @param reportCode
     * @return
     */
    Report getReportByCode(String reportCode);

    /**
     * 根据sqlId获取ReportSql实体
     *
     * @param sqlId
     * @return
     */
    ReportSql getReportSqlById(Long sqlId);

    /**
     * 根据报表id查询出所有的报表字段
     * @param reportId
     * @return
     */
    List<ReportColumn> listColumnByReportId(Long reportId);

    /**
     * 查询指定报表的所有查询字段
     * @param reportId
     * @return
     */
    List<QueryField> listQueryFieldByReportId(Long reportId);
}
